#!/user/bin/env python
# -*- coding: utf-8 -*-
''' 
Author: Sjy
LastEditTime: 2024-08-27 11:43:36
Description:  文件处理通用工具
'''

__all__= []

from PyQt5 import QtWidgets
import os
import json
import shutil
import subprocess
import chardet

def get_basename(file):
    return os.path.basename(file)

def get_file_extesion(file):
    return  os.path.splitext(get_basename(file) )[1]

def get_file_name(file):
    filename = get_basename(file)
    fileExtesion = get_file_extesion(filename)
    return filename.replace(fileExtesion, "")
def get_file_encoding(file):
    if not os.path.exists(file):
        return "utf-8"
    with open(file, 'rb') as f:
        content = f.read()
    return chardet.detect(content)['encoding']
def open_json(file, encoding="utf-8"):
    if os.path.exists(file):
        # 先检查下文件的编码 
        try:
            # encoding = get_file_encoding(file)    
            with open(file, "r", encoding=encoding) as load_f:
                return json.load(load_f)
        except:
            curencoding = get_file_encoding(file)    
            print(f"当前数据文件编码为{curencoding}不符合要求，请修改编码为{encoding}")
            return {}
    return {}
def save_json(file, data, encoding="utf-8", removeNone=False):
    """
    保存 JSON 数据到文件
    Args:
        file (str): 文件路径
        data (dict): 要保存的数据
        encoding (str, optional): 文件编码. Defaults to "utf-8".
        removeNone (bool, optional): 是否移除值为None的键. Defaults to False.
    Returns:
        bool: 保存是否成功
    """
    def remove_none_values(obj):
        """
        递归移除值为None的键
        Args:
            obj: 要处理的对象
        Returns:
            处理后的对象
        """
        if isinstance(obj, dict):
            return {k: remove_none_values(v) for k, v in obj.items() if not (removeNone and v is None)}
        elif isinstance(obj, list):
            return [remove_none_values(item) for item in obj]
        else:
            return obj

    try:
        # 检查文件是否存在且为只读
        if os.path.exists(file):
            # 获取当前文件权限
            current_permissions = os.stat(file).st_mode
            # 如果文件是只读的，修改权限为可写
            if not (current_permissions & 0o200):  # 0o200 表示用户可写权限
                os.chmod(file, 0o777)  # 修改为所有用户可读写执行
        
        # 如果需要移除None值，先处理数据
        if removeNone:
            data = remove_none_values(data)
        
        # 保存文件
        with open(file, "w", encoding=encoding) as f:
            json.dump(data, f, ensure_ascii=False, indent=4)
        return True
    except Exception as e:
        print(f"保存文件失败: {str(e)}")
        return False
def read(file):
    return open_json(file)
# 本地磁盘选择文件
def import_file(fileType:str="*",  file=None, parent=None):
    showFileType = fileType != "*" and fileType or "全部"
    fileName_choose = QtWidgets.QFileDialog.getOpenFileName(parent , "请选择{}文件".format(showFileType),file or "data\\", "{} Files (*.{});".format(showFileType, fileType))
    if not fileName_choose or fileName_choose[0] == "":
        return
    (file, fileType) = fileName_choose
    (filename, extension) = os.path.splitext(os.path.basename(file))
    return {
        "file": file,
        "fileType": fileType.lower(),
        "filename": filename,
        "extension": extension.lower(),
    }
def import_custom_type_file(fileType, file=None, parent=None):
    # All Files (*.*);;Text Files (*.txt);;Image Files (*.png *.xpm *.jpg)
    fileName_choose = QtWidgets.QFileDialog.getOpenFileName(parent, "打开文件",file or "data\\", fileType)
    if not fileName_choose or fileName_choose[0] == "":
        return
    (file, fileType) = fileName_choose
    (filename, extension) = os.path.splitext(os.path.basename(file))
    return {
        "file": file,
        "fileType": fileType.lower(),
        "filename": filename,
        "extension": extension.lower(),
    }
# 本地磁盘选择文件
def import_dir(dir=None, parent=None):
    dir = QtWidgets.QFileDialog.getExistingDirectory(parent,  "选择文件夹", dir or "data\\")
    if not dir or dir == "":
        return {}
    return {
        "dir": dir,
    }

# 本地磁盘保存文件
def save_file(fileType:str="*",  file=None, parent=None):
    showFileType = fileType != "*" and fileType or "全部"
    fileName_choose = QtWidgets.QFileDialog.getSaveFileName(parent , "请选择{}文件".format(showFileType),file or "data\\", "{} Files (*.{});".format(showFileType, fileType))
    if not fileName_choose or fileName_choose[0] == "":
        return
    (file, fileType) = fileName_choose
    (filename, extension) = os.path.splitext(os.path.basename(file))
    return {
        "file": file,
        "fileType": fileType.lower(),
        "filename": filename,
        "extension": extension.lower(),
    }


def create_dir(dir):
    if not os.path.exists(dir):
        os.makedirs(dir)
    return dir
def open_model(fileType:str='VTK', parent=None):
    """获取打开指定类型的文件"""
    dictFile = import_file(fileType, parent=parent) or {}
    return dictFile.get('file')

def copy_file(src, dist):
    """python 拷贝文件
    1. 判断源文件和目标文件是否同一个文件
    2. 判断目标文件是否存在，存在则删除
    """

    # src = src.replace("\\", "/")
    # dist = dist.replace("\\", "/")
    # # 将文件名都转成小写字符进行比较
    # srcLower = src.lower()
    # distLower = dist.lower()

    # if srcLower == distLower:
    #     return
    # if os.path.exists(dist):
    #     os.remove(dist) #文件存在则先删除文件
    # shutil.copy(src, dist) #复制文件到新文件夹
    try:
        # 获取规范化的绝对路径
        src_abs = os.path.normpath(os.path.abspath(src))
        dst_abs = os.path.normpath(os.path.abspath(dist))
        # 使用 normcase 处理大小写问题进行比较
        if os.path.normcase(src_abs) == os.path.normcase(dst_abs):
            print("源文件和目标文件相同，无需复制")
            return True
            
        # 确保目标目录存在
        dst_dir = os.path.dirname(dst_abs)
        if not os.path.exists(dst_dir):
            try:
                os.makedirs(dst_dir)
            except Exception as e:
                print(f"创建目标目录失败: {str(e)}")
                return False
            
        # 如果目标文件存在，先修改权限再删除
        if os.path.exists(dst_abs):
            try:
                # 修改文件权限为可写
                os.chmod(dst_abs, 0o666)
                os.remove(dst_abs)
            except Exception as e:
                print(f"删除目标文件失败: {str(e)}")
                return False
                
        # 复制文件
        shutil.copy(src_abs, dst_abs)
        return True
    except Exception as e:
        print(f"复制文件失败: {str(e)}")
        return False

def remove_file(file):
    if os.path.exists(file):
        os.remove(file)
        return True
    return False
def remove_dir(dir):
    if os.path.exists(dir):
        shutil.rmtree(dir)
        return True
    return False

def open_file(file):
    file = file.replace("\\", "/")
    # 将字符串file按照'/'分割成一个列表
    return subprocess.Popen(["start", "", file], shell=True)
if __name__ == "__main__":
    pass

